package utils

import (
	"crypto/md5"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"github.com/zeromicro/go-zero/core/logx"
	"io"
	"log"
	"math/rand"
	"net"
	"net/http"
	"net/url"
	"os"
	"strconv"
	"strings"
	"time"
	"unsafe"
	"wave-service/server/app/internal/config"
)

// RemoteIp 返回远程客户端的 IP，如 192.168.1.1
func RemoteIp(req *http.Request) string {
	remoteAddr := req.RemoteAddr
	if ip := req.Header.Get("X-Real-IP"); ip != "" {
		remoteAddr = ip
	} else if ip = req.Header.Get("X-Forwarded-For"); ip != "" {
		remoteAddr = ip
	} else {
		remoteAddr, _, _ = net.SplitHostPort(remoteAddr)
	}

	if remoteAddr == "::1" {
		remoteAddr = "127.0.0.1"
	}

	return remoteAddr
}

// 获得随机变量
func RandomString(n int) string {
	var letters = []byte("abcdefghijklmnopqrstuvwxyzABDEFGHIJKLMNOPQRSTUVWXYZ")
	result := make([]byte, n)

	rand.Seed(time.Now().Unix())
	for i := range result {
		result[i] = letters[rand.Intn(len(letters))]
	}

	return string(result)
}

func PathExists(path string) (bool, error) {
	_, err := os.Stat(path)
	if err == nil {
		return true, nil
	}
	if os.IsNotExist(err) {
		return false, nil
	}
	return false, err
}

// 小写
func Md5Encode(data string) string {
	h := md5.New()
	h.Write([]byte(data)) // 需要加密的字符串为 123456
	cipherStr := h.Sum(nil)
	return hex.EncodeToString(cipherStr)
}

func ValidatePasswd(plainpwd, salt, passwd string) bool {
	return Md5Encode(plainpwd+salt) == passwd
}

func MakePasswd(plainpwd, salt string) string {
	return Md5Encode(plainpwd + salt)
}

// 将IP地址转化为二进制String
func Ip2binary(ip string) string {
	str := strings.Split(ip, ".")
	var ipstr string
	for _, s := range str {
		i, err := strconv.ParseUint(s, 10, 8)
		if err != nil {
			fmt.Println(err)
		}
		ipstr = ipstr + fmt.Sprintf("%08b", i)
	}
	return ipstr
}

func IpMatchPrivate(ip string) bool {
	ipb := Ip2binary(ip)
	private1 := Ip2binary("127.0.0.1")
	private2 := Ip2binary("10.0.0.1")
	private3 := Ip2binary("192.168.0.0")
	//log.Println(ipb)
	//log.Println(private1)
	//log.Println(private2)
	//log.Println(private3)
	if strings.EqualFold(ipb[0:8], private1[0:8]) {
		return true
	}
	if strings.EqualFold(ipb[0:8], private2[0:8]) {
		return true
	}
	if strings.EqualFold(ipb[0:16], private3[0:16]) {
		return true
	}

	return false
}

func StringToBytes(data string) []byte {
	return *(*[]byte)(unsafe.Pointer(&data))
}

func IpPlace(ip string, appkey string, sign string) (province string, city string) {
	province = "本地"
	city = "本机"
	if IpMatchPrivate(ip) == false {
		data := url.Values{"app": {"ip.get"}, "ip": {ip}, "appkey": {appkey}, "sign": {sign}, "format": {"json"}}
		resp, err := http.PostForm("https://sapi.k780.com", data)
		//url := "https://sapi.k780.com?app=ip.get&ip=" + ip + "&appkey=" + appkey + "&sign=" + sign + "&format=json"
		//log.Println(url)
		//clt := http.Client{}
		//resp, err := clt.Get(url)
		if err != nil {
			logx.Errorf("接口报错: %v", err)
			return "报错", "未知"
		}
		body, _ := io.ReadAll(resp.Body)
		defer resp.Body.Close()

		var m = make(map[string]interface{})
		err = json.Unmarshal(body, &m)
		if err != nil {
			logx.Errorf("接口报错: %v", err.Error())
			return "报错", "未知"
		}
		suc := m["success"]
		if suc == "1" {
			type jsonResult struct {
				Status string `json:"status"`
				Att    string `json:"att"`
			}
			resByre, resByteErr := json.Marshal(m["result"])
			if resByteErr != nil {
				log.Println(resByteErr.Error())
				logx.Errorf("接口报错: %v", resByteErr.Error())
				return "报错", "未知"
			}
			var res jsonResult
			jsonRes := json.Unmarshal(resByre, &res)
			if jsonRes != nil {
				log.Println(jsonRes.Error())
				logx.Errorf("接口报错: %v", jsonRes.Error())
				return "报错", "未知"
			}

			if res.Status == "OK" {
				p := strings.Split(res.Att, ",")
				if len(p) > 2 {
					province = p[1]
					city = p[2]
				} else {
					province = p[1]
					city = province
				}

			} else {
				log.Println("接口报错: ", ip, res.Status)
				logx.Errorf("接口报错: %v %v", ip, res.Status)
				return "报错", "未知"
			}

		} else {
			log.Println("接口报错: ", ip)
			logx.Errorf("接口报错: %v", ip)
			return "报错", "未知"
		}
	}

	return province, city
}

// 获得图片URL
func TransformImageUrl(config config.Config, path string) (url string) {
	if config.OssType == "local" {
		url = fmt.Sprintf("%s%d%s", "http//127.0.0.1:", config.Port, path)
	} else if config.OssType == "qiniu" {
		url = config.Qiniu.Domain
		if config.Qiniu.UseHttps {
			url = "https://" + url + path
		} else {
			url = "http://" + url + path
		}
		url += config.Qiniu.ImgStyle
	}

	return url
}

// 去除图片域名前缀
func RemoveImageDomain(config config.Config, url string) (path string) {
	a1 := strings.Split(url, "//")[1]
	a2 := strings.Split(a1, "/")[1:]
	path = "/" + strings.Join(a2, "/")
	if config.OssType == "qiniu" && config.Qiniu.ImgStyle != "" {
		path = strings.Replace(path, config.Qiniu.ImgStyle, "", 1)
	}
	log.Println("去除图片域名后图片地址=" + path)

	return path
}
